package edu.cuit.avatar.concurrent;

/**
 * @author <a href="mailto:1020zhaodan@163.com">Adan</a>
 * @version 1.0
 * @date 2025/7/17 10:42
 */
public class BankDeadLockDemo {
    private static class Account{
        private String name;
        private int balance;

        public Account(String name, int balance) {
            this.name = name;
            this.balance = balance;
        }

        public int getBalance() {
            return balance;
        }

        public String getName() {
            return name;
        }

        public void deposit(int amount){
            balance += amount;
        }

        public void withdraw(int amount){
            balance -= amount;
        }

        @Override
        public String toString() {
            return  name + ':' + balance;
        }
    }

    public static void transfer(Account from, Account to, int amount){
        Account object1 = from.name.compareTo(to.name) < 0 ? from : to;
        Account object2 = object1 == from ? to : from;
        synchronized (object1){
            System.out.println(Thread.currentThread().getName() + " acquired lock on " + from);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized (object2){
                System.out.println(Thread.currentThread().getName() + " acquired lock on " + to);
                if(from.balance >= amount){
                    from.withdraw(amount);
                    to.deposit(amount);
                    System.out.println("transfer successful!");
                } else
                    System.out.println("insufficient balance");
            }
        }
    }

    public static void main(String[] args) {
        Account peppa = new Account("Peppa", 1000);
        Account jorge = new Account("jorge", 1000);

        new Thread(()-> transfer(peppa, jorge, 500)).start();
        new Thread(()-> transfer(jorge, peppa, 500)).start();

    }
}
